using GrapeCity.Forguncy.Commands;
using GrapeCity.Forguncy.Plugin;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using SeleiumLoginGetHttp.qita;
using GrapeCity.Forguncy;
using static SeleiumLoginGetHttp.qita.qitatxt;
using System.Security.Claims;
using System.Linq;

namespace SeleiumLoginGetHttp
{
    [Icon("pack://application:,,,/SeleiumLoginGetHttp;component/Resources/Icon.png")]
    [Designer("SeleiumLoginGetHttp.Designer.SeleiumLoginGetHttpServerCommandDesigner, SeleiumLoginGetHttp")]
    [Description("基于seleium模拟登录网站获取http请求内容及响应内容，只支持windows与linux服务器。")]
    public class SeleiumLoginGetHttpServerCommand : Command, ICommandExecutableInServerSideAsync
    {
        [Required]
        [Description("指打开网址后是否需要先点击页面某个地方，然后再开始输入账户密码等操作。")]
        [ComboProperty(ValueList = "xuyao|wuxu", DisplayList = "需要先点击页面|无需点击页面直接输入账户")]
        public string 使用方式 { get; set; } = "wuxu";

        [FormulaProperty]
        [Required]
        [Description("指要点击的元素在页面的xpath路径")]
        [DisplayName("要点击的xpath")]
        public object AddNumber1
        {
            get
            {
                if (使用方式 == "wuxu") return null;
                return _addNumber1;
            }
            set
            {
                _addNumber1 = value;
            }
        }
        private object _addNumber1;


        [RadioGroupProperty(ValueList = "shi01|fou01", DisplayList = "是|否")]
        public string 是否有子账户 { get; set; }

        //设置单选框如果等于则为空
        [FormulaProperty]
        [Required]
        [Description("指要输入子账户的输入框元素在也页面所在的xpath路径")]
        [DisplayName("子账户输入框xpath")]
        public object AddNumber8
        {
            get
            {
                if (是否有子账户 == "fou01") return null;
                return _addNumber8;
            }
            set
            {
                _addNumber8 = value;
            }
        }
        private object _addNumber8;

        //判断2个选项是否可见，如果等于则可见
        public override bool GetDesignerPropertyVisible(string propertyName, CommandScope commandScope)
        {
            if (propertyName == nameof(AddNumber1))
            {
                return 使用方式 == "xuyao";
            }
            else if (propertyName == nameof(AddNumber8))
            {
                return 是否有子账户 == "shi01";
            }
            else if (propertyName == nameof(AddNumber9))
            {
                return 是否有子账户 == "shi01";
            }
            else if (propertyName == nameof(查询关键字))
            {
                //当 返回结果类别 等于 "qingqiu" 或者等于 "xiangying" 时可见的需求
                //return 返回结果类别 == "qingqiu" && 使用方式 == "xiangying";  并且 才可见
                return 返回结果类别 == "qingqiu" || 返回结果类别 == "xiangying";
            }
            return base.GetDesignerPropertyVisible(propertyName, commandScope);
        }

        [FormulaProperty]
        [Required]
        [Description("要输入的子账户信息，支持公式")]
        [DisplayName("子账户")]
        public object AddNumber9
        {
            get
            {
                if (是否有子账户 == "fou01") return null;
                return _addNumber9;
            }
            set
            {
                _addNumber9 = value;
            }
        }
        private object _addNumber9;


        [FormulaProperty]
        [Required]
        [Description("账户名称信息，支持公式")]
        [DisplayName("账户")]
        public object AddNumber2 { get; set; }

        [FormulaProperty]
        [Required]
        [Description("密码明文，支持公式")]
        [DisplayName("密码")]
        public object AddNumber3 { get; set; }

        [FormulaProperty]
        [Required]
        [Description("要模拟登录访问的网站地址，必须带有http或者https开头")]
        [DisplayName("网址")]
        public object AddNumber4 { get; set; }

        [FormulaProperty]
        [Required]
        [Description("账户输入框元素在页面所在的xpath路径")]
        [DisplayName("账户输入框xpath")]
        public object AddNumber5 { get; set; }

        [FormulaProperty]
        [Required]
        [Description("密码输入框元素在页面所在的xpath路径")]
        [DisplayName("密码输入框xpath")]
        public object AddNumber6 { get; set; }

        [FormulaProperty]
        [Required]
        [Description("登录按钮元素在页面所在的xpath路径")]
        [DisplayName("登录按钮xpath")]
        public object AddNumber7 { get; set; }

        [Required]
        [Description("全部内容message每行信息总长度则排除低于300大于5000，请求内容及相应内容对应你要获取的结果在网页中post或者get的位置")]
        [ComboProperty(ValueList = "quanbu|qingqiu|xiangying", DisplayList = "全部内容|请求内容|响应内容")]
        public string 返回结果类别 { get; set; } = "quanbu";

        [Description("要查找请求内容或响应内容的json字段属性名称(对象名)")]
        [ListProperty]
        public List<MyObj> 查询关键字 { get; set; }
        public List<string> AddNumber10()
        {
            if (返回结果类别 == "quanbu")
            {
                return null;
            }
            else
            {
                return 查询关键字.Select(item => item.查询关键字).ToList();
            }
        }


        //复选框表示布尔值是或否，
        [Required]
        [Description("如果显示则服务器会弹出一个谷歌浏览器执行模拟登录动作，注意且只有windows服务器可用。")]
        public bool 是否显示浏览器进展情况 { get; set; }

        [ResultToProperty]
        [DisplayName("返回结果")]
        public string ResultTo { get; set; } = "返回结果";

        [ResultToProperty]
        [DisplayName("返回结果1")]
        public string ResultTo1 { get; set; } = "返回结果1";


        public class MyObj : ObjectPropertyBase
        {
            public string 查询关键字 { get; set; }
        }

        public async Task<ExecuteResult> ExecuteAsync(IServerCommandExecuteContext dataContext)
        {
            var add1 = await dataContext.EvaluateFormulaAsync(AddNumber1); // 计算的一个加数的公式值
            var add2 = await dataContext.EvaluateFormulaAsync(AddNumber2); // 计算的一个加数的公式值
            var add3 = await dataContext.EvaluateFormulaAsync(AddNumber3); // 计算的一个加数的公式值
            var add4 = await dataContext.EvaluateFormulaAsync(AddNumber4); // 计算的一个加数的公式值
            var add5 = await dataContext.EvaluateFormulaAsync(AddNumber5); // 计算的一个加数的公式值
            var add6 = await dataContext.EvaluateFormulaAsync(AddNumber6); // 计算的一个加数的公式值
            var add7 = await dataContext.EvaluateFormulaAsync(AddNumber7); // 计算的一个加数的公式值
            var add8 = await dataContext.EvaluateFormulaAsync(AddNumber8); // 计算的一个加数的公式值
            var add9 = await dataContext.EvaluateFormulaAsync(AddNumber9); // 计算的一个加数的公式值
            //循环列表每个值处理并组装成一个新的列表
            var ass10 = new List<string>();
            foreach (var item in AddNumber10())
            {
                var addResult = (await dataContext.EvaluateFormulaAsync(item)).ToString();//参数值可能是一个公式
                ass10.Add(addResult);
            }
            string ass1 = add1?.ToString() ?? string.Empty;//转换为字符串并判断是否空值
            string ass2 = add2?.ToString() ?? string.Empty;//转换为字符串并判断是否空值
            string ass3 = add3?.ToString() ?? string.Empty;//转换为字符串并判断是否空值
            string ass4 = add4?.ToString() ?? string.Empty;//转换为字符串并判断是否空值
            string ass5 = add5?.ToString() ?? string.Empty;//转换为字符串并判断是否空值
            string ass6 = add6?.ToString() ?? string.Empty;//转换为字符串并判断是否空值
            string ass7 = add7?.ToString() ?? string.Empty;//转换为字符串并判断是否空值
            string ass8 = add8?.ToString() ?? string.Empty;//转换为字符串并判断是否空值
            string ass9 = add9?.ToString() ?? string.Empty;//转换为字符串并判断是否空值

            JObject result = qitatxt.PerformLoginAndCaptureNetworkInfo(ass7, ass5, ass6, ass2, ass3, ass4, 使用方式, ass1, 返回结果类别, 是否有子账户, ass8, ass9, ass10, 是否显示浏览器进展情况);

            dataContext.Parameters[ResultTo] = result;

            dataContext.Parameters[ResultTo] = ass10;

            return new ExecuteResult();
        }
        



        public override string ToString()
        {
            return "模拟登录获取http请求响应服务端命令";
        }

        public override CommandScope GetCommandScope()
        {
            return CommandScope.ExecutableInServer;
        }
    }
}
